﻿using System;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using mmCore.Common;
using mmUI.Managers;
using mmUI.ViewModels;

namespace mmUI.Windows
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private enum SlideState
        {
            Movies, Episodes, Search
        }

        private SlideState _mState = SlideState.Movies;
        private bool _mClosing = false;
        private bool _mCanClose = false;

        public MainWindow()
        {
            InitializeComponent();

            try
            {
                DataContext = new MainWindowVm(Dispatcher);
                ExceptionManager.OnException += ExceptionManager_OnException;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Initialization error:\r\n\r\n{0}",
                   ex), "MovieManager", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void ExceptionManager_OnException(Exception ex)
        {
            Dispatcher.Invoke(new Action(() => MessageBox.Show(string.Format("Runtime exception:\r\n\r\n{0}",
                   ex), "MovieManager", MessageBoxButton.OK, MessageBoxImage.Error)), DispatcherPriority.Render);
        }

        private void ButtonClick1(object sender, RoutedEventArgs e)
        {
            if (_mState == SlideState.Movies)
            {
                _mBtSlider.Content = "Back to movies";
                _mState = SlideState.Episodes;
                view1.BeginStoryboard((Storyboard) Resources["slideLeftToRight"]);
            }
            else if(_mState == SlideState.Episodes)
            {
                _mBtSlider.Content = "Show episodes";
                _mState = SlideState.Movies;
                view1.BeginStoryboard((Storyboard)Resources["slideRightToLeft"]);
            }
            else
            {
                _mBtSlider.Content = "Show episodes";
                var vm = (DataContext as MainWindowVm);
                if(vm != null)
                {
                    vm.SliderEnabled = vm.SelectedMovie != null ? true : false;
                    vm.SearchString = string.Empty;
                    vm.SearchResult.Clear();
                }
                _mState = SlideState.Movies;
                view1.BeginStoryboard((Storyboard)Resources["slideFromSearch"]);
            }
        }

        private void WindowLoaded(object sender, RoutedEventArgs e)
        {
            Title += string.Format(" v{0}", Config.AppVersion);

            if (Config.ProviderType == ProviderType.Unknown)
            {
                if(MessageBox.Show("Do you want to use google account to store data?", "Google account", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    Config.ProviderType = ProviderType.GoogleAccount;
                }
                else
                {
                    Config.ProviderType = ProviderType.XmlFile;
                }
            }
            if (Config.ProviderType == ProviderType.GoogleAccount)
            {
                if(!Config.SavePassword || string.IsNullOrEmpty(Config.Password) || string.IsNullOrEmpty(Config.GoogleLogin))
                {
                    var lw = new LoginWindow();
                    lw.ShowDialog();
                    Config.ProviderType = lw.Canceled ? ProviderType.XmlFile : ProviderType.GoogleAccount;
                }
            }

            MovieManager.OnLoaded += movies => Dispatcher.Invoke(new Action(() =>
            {
                if(movies == null)
                {
                    MessageBox.Show("Could not access movie data, local data file will be used.", "Connection problem", MessageBoxButton.OK, MessageBoxImage.Warning);
                    Config.ProviderType = ProviderType.XmlFile;
                    MovieManager.LoadMovies(System.IO.Path.Combine(Config.AppDir, "data.xml"));
                    return;
                }
                MovieManager.AcceptLoadedMovies(movies);
                var vm = DataContext as MainWindowVm;
                if (vm != null)
                {
                    vm.SelectedMovie = MovieManager.Movies.ToList().FirstOrDefault();
                    vm.ReloadAllMovies.Execute(null);
                }
                UpdateManager.OnUpdateAvailable += (version) => Dispatcher.Invoke(new Action(() =>
                {
                    if (Config.ShowUpdatesNotifications && 
                        MessageBox.Show(string.Format("Version {0} available. Do you want to download new version now?", version), "Update available", 
                        MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        Utils.OpenWebPage(UpdateManager.WebUrl);
                    }
                    Title += string.Format(" :: version {0} available! go to: mmanager.codeplex.com", version);
                }));
                UpdateManager.CheckUpdates();
                _mLoading.BeginStoryboard((Storyboard)Resources["loadSlide"]);
            }), DispatcherPriority.Render);

            ThreadPool.QueueUserWorkItem(o => MovieManager.LoadMovies(System.IO.Path.Combine(Config.AppDir, "data.xml")));
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if(_mCanClose)
            {
                return;
            }
            e.Cancel = true;
            if (_mClosing)
            {
                return;
            }
            _mClosing = true;
            _mLoading.BeginStoryboard((Storyboard)Resources["saveSlide"]);
            MovieManager.OnSaved += () => Dispatcher.Invoke(new Action(() =>
            {
                _mCanClose = true;
                Close();
            }));
            ThreadPool.QueueUserWorkItem(o => MovieManager.SaveMovies());
        }

        private void WindowClosed(object sender, EventArgs e)
        {
            
        }

        private void ButtonClick(object sender, RoutedEventArgs e)
        {
            if (_mState == SlideState.Episodes || string.IsNullOrEmpty(_mTbSearch.Text))
            {
                return;
            }

            if(_mState == SlideState.Movies)
            {
                _mBtSlider.Content = "Back to movies";
                _mState = SlideState.Search;
                view1.BeginStoryboard((Storyboard)Resources["slideToSearch"]);
            }
        }

        private void MBtSelectClick(object sender, RoutedEventArgs e)
        {
            if (_mState == SlideState.Search)
            {
                _mState = SlideState.Movies;
                _mBtSlider.Content = "Show episodes";
                view1.BeginStoryboard((Storyboard) Resources["slideFromSearch"]);
            }
        }

        private void MTbSearchTextChanged(object sender, TextChangedEventArgs e)
        {
            if (_mTbSearch != null)
            {
                _mTbSearch.GetBindingExpression(TextBox.TextProperty).UpdateSource();
            }
        }

        private void _mBtSettings_Click(object sender, RoutedEventArgs e)
        {
            var sw = new SettingsWindow();
            sw.ShowDialog();
        }
    }
}
